package com.s.client;

import com.c1.rpc.ServerData;
import com.google.common.collect.Lists;
import com.s.core.root.*;
import com.s.core.root.Basic;
import com.s.core.root.CodeFeature;
import com.s.core.root.data._AllData;
import com.s.core.root.strategy.Strategy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhangjiangnan
 */
@Service
@Slf4j
public class ServerDataImpl implements ServerData {
    private final List<String> excludeCodes = Lists.newArrayList();

    @Override
    public List<_AllData> data(List<String> codes, String date) {
        return codes.stream().map(code -> Ad.me().getDaily(date, code)).
                filter(Objects::nonNull).
                map(_AllData::new).collect(Collectors.toList());
    }

    @Override
    public List<String> codes(String content, String date, boolean isExcludeMode, boolean isExcludeCanNotBuy) {
        if (!Ad.me().getDateList().contains(date)) {
            return null;
        }
        List<String> codes = Lists.newArrayList();
        TreeMap<Integer, String> unsortedMap = new TreeMap<>();
        for (Basic basic : Ad.me().getBasicList()) {
            String code = basic.getCode();
            if (isExcludeCanNotBuy && !CodeFeature.isCanBuy(code)) {
                continue;
            }
            int nameIndex = content.indexOf(basic.getName());
            int codeIndex = content.indexOf(code);
            if ((nameIndex != -1 || codeIndex != -1) && !codes.contains(code)) {
                int index = Math.max(nameIndex, codeIndex);
                unsortedMap.put(index, code);
                codes.add(code);
            }
        }
        List<String> result = new ArrayList<>(unsortedMap.values());
        if (isExcludeMode) {
            result.removeAll(excludeCodes);
            excludeCodes.addAll(result);
        }
        return result;
    }

    @Override
    public String date(boolean next, String date) {
        return next ? Ad.me().nextDate(date) : Ad.me().preDate(date);
    }

    @Override
    public String zt(String date) {
        StringBuilder result = new StringBuilder();
        result.append("日期:").append(date).append("\n");
        List<String> ztCodes = Ad.me().getCodes().stream().
                map(code -> Ad.me().getDaily(date, code)).
                filter(d -> d != null && CodeFeature.isCanBuy(d.code) && d.isZt()).
                map(D::getCode).collect(Collectors.toList());
        result.append("涨停:(").append(ztCodes.size()).append("个):\n");
        result.append(ztCodes);
        return result.toString();
    }

    @Override
    public String strategyList(String date) {
        List<Strategy.StrategyCode> strategyCodes = Strategy.me().get(Ad.me().getCodes(), date);
        StringBuilder result = new StringBuilder();
        result.append("日期:").append(date).append("\n");
        result.append("共").append(strategyCodes.size()).append("个\n");
        for (Strategy.STRATEGY strategy : Strategy.STRATEGY.values()) {
            List<String> codes = strategyCodes.stream().filter(t -> t.getStrategy() == strategy).
                    map(Strategy.StrategyCode::getCode).collect(Collectors.toList());
            result.append(strategy).append("(").append(codes.size()).append("个):\n");
            result.append(codes).append("\n");
        }
        List<String> allStrategyCodes = strategyCodes.stream().map(Strategy.StrategyCode::getCode).collect(Collectors.toList());
        result.append("\nTOP ZT\n").append(Strategy.me().topZt(date, allStrategyCodes));
        return result.toString();
    }

    @Override
    public String strategyTest(String code, String date) {
        if (code != null && date != null) {
            Strategy.StrategyCode strategyCodes = Strategy.me().get(code, date);
            String value = strategyCodes == null ? "NONE STRATEGY" : strategyCodes.getStrategy().toString();
            return code + "," + date + "," + value;
        }
        int unMatchCount = 0;
        int unEqualsCount = 0;
        StringBuilder result = new StringBuilder("Case Test Result:\n");
        for (CaseA c : Ac.me().list()) {
            if (Ad.me().getDaily(c.date, c.code) == null) {
                continue;
            }
            Strategy.StrategyCode strategyCode = Strategy.me().get(c.code, c.date);
            if (strategyCode == null) {
                result.append("un match case,\"").append(c.code).append("\", \"").append(c.date).append("\"\n");
//                System.out.println(c.code + "," + c.date + "," + c.strategy);
                unMatchCount++;
                continue;
            }
            if (strategyCode.getStrategy() != c.strategy) {
                result.append("un equals case,\"").append(c.code).append("\", \"").append(c.date).append("\"\n");
                unEqualsCount++;
//                System.out.println(c.code + "," + c.date + "," + strategyCode.getStrategy());
            } else {
//                System.out.println(c.code + "," + c.date + "," + c.strategy);
            }
        }
        result.append("END.").append("unMatchCount:").append(unMatchCount).append(", unEqualsCount:").append(unEqualsCount).append("\n");
        return result.toString();
    }

    @Override
    public CaseA strategyCase(String code, String date, boolean isNext) {
        if (code == null || date == null) {
            return Ac.me().first(isNext);
        }
        return Ac.me().get(isNext, code, date);
    }
}
